﻿using NUnit.Framework;
using Ninject.Modules;
using Ninject;
using System.Net.DnsToolkit.Bastard;
using System.Net.DnsToolkit.Bastard.PacketGenerator;
using System.Net.DnsToolkit.Resolver;
using System.Net.DnsToolkit.Configuration;
using System.Net.DnsToolkit.SocketAsync;
using System.Net.DnsToolkit.Packet;

namespace System.Net.DnsToolkit.TestUnit.Bastard {
    [TestFixture]
    public class LousyBastardTest {

        class TestMultipleSameQuestionsModule : NinjectModule {
            public override void Load() {

                Bind<IDnsServerProvider>().To<StaticDnsServerProvider>();
                Bind<UdpClientAsync>().ToSelf();
                Bind<IPacketGenerator>()
                    .To<MultipleSameQuestions>()
                    .WithConstructorArgument("number", 10);


            }
        }
        [Test]
        public void TestMultipleSameQuestions() {


            var modules = new NinjectModule[] {
                new TestMultipleSameQuestionsModule(),
                new DnsReaderStreamModule(),
                new DnsWriterJsonModule()
            };

            using (var kernel = new StandardKernel(modules)) {

                var lousy = kernel.Get<LousyBastard>();
                var packet = kernel.Get<MultipleSameQuestions>();
                IMessage result = lousy.Scratch(packet);
                Assert.IsNull(result, "result");

            }


        }


        class TestSelfAnsweringQuestionModule : NinjectModule {
            public override void Load() {

                Bind<IDnsServerProvider>().To<StaticDnsServerProvider>();
                Bind<UdpClientAsync>().ToSelf();
                Bind<IPacketGenerator>().To<SelfAnsweringQuestion>();


            }
        }
        [Test]
        public void TestSelfAnsweringQuestion() {


            var modules = new NinjectModule[] {
                new TestSelfAnsweringQuestionModule(),
                new DnsReaderStreamModule(),
                new DnsWriterJsonModule()
            };

            using (var kernel = new StandardKernel(modules)) {

                var lousy = kernel.Get<LousyBastard>();
                var packet = kernel.Get<SelfAnsweringQuestion>();
                var result = lousy.Scratch(packet);

                Assert.IsNotNull(result, "result");
                Assert.AreEqual(RCodeEnum.FormatError, result.Header.ResponseCode, "ResponseCode");
                Assert.AreEqual(0, result.Header.AnswerCount, "AnswerCount");
                Assert.AreEqual(0, result.Header.AuthorityCount, "AuthorityCount");
                Assert.AreEqual(0, result.Header.QuestionCount, "QuestionCount");
                Assert.AreEqual(0, result.Header.ResourceCount, "ResourceCount");

            }


        }


        class TestSelfRebindingAuthorityAdditionalModule : NinjectModule {
            public override void Load() {

                Bind<IDnsServerProvider>().To<StaticDnsServerProvider>();
                Bind<UdpClientAsync>().ToSelf();
                Bind<IPacketGenerator>().To<SelfRebindingAuthorityAdditional>();


            }
        }
        [Test]
        public void TestSelfRebinding() {

            var modules = new NinjectModule[] {
                new TestSelfRebindingAuthorityAdditionalModule(),
                new DnsReaderStreamModule(),
                new DnsWriterJsonModule()
            };

            using (var kernel = new StandardKernel(modules)) {

                var lousy = kernel.Get<LousyBastard>();
                var packet = kernel.Get<SelfRebindingAuthorityAdditional>();
                var result = lousy.Scratch(packet);

                Assert.IsNotNull(result, "result");
                Assert.AreEqual(RCodeEnum.FormatError, result.Header.ResponseCode, "ResponseCode");
                Assert.AreEqual(0, result.Header.AnswerCount, "AnswerCount");
                Assert.AreEqual(0, result.Header.AuthorityCount, "AuthorityCount");
                Assert.AreEqual(0, result.Header.QuestionCount, "QuestionCount");
                Assert.AreEqual(0, result.Header.ResourceCount, "ResourceCount");

            }


        }


        class TestSelfRebindingAdditionalModule : NinjectModule {
            public override void Load() {

                Bind<IDnsServerProvider>().To<StaticDnsServerProvider>();
                Bind<UdpClientAsync>().ToSelf();
                Bind<IPacketGenerator>().To<SelfRebindingAdditional>();


            }
        }
        [Test]
        public void TestSelfRebindingAdditional() {


            var modules = new NinjectModule[] {
                new TestSelfRebindingAdditionalModule(),
                new DnsReaderStreamModule(),
                new DnsWriterJsonModule()
            };

            using (var kernel = new StandardKernel(modules)) {

                var lousy = kernel.Get<LousyBastard>();
                var packet = kernel.Get<SelfRebindingAdditional>();
                var result = lousy.Scratch(packet);

                Assert.IsNotNull(result, "result");
                Assert.AreEqual(RCodeEnum.FormatError, result.Header.ResponseCode, "ResponseCode");
                Assert.AreEqual(0, result.Header.AnswerCount, "AnswerCount");
                Assert.AreEqual(0, result.Header.AuthorityCount, "AuthorityCount");
                Assert.AreEqual(0, result.Header.QuestionCount, "QuestionCount");
                Assert.AreEqual(0, result.Header.ResourceCount, "ResourceCount");

            }


        }
        
    }
}
